package Helper;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * Created by Administrator on 2018/1/6 0006.
 */

public class MD5 {
    /**
     * 列表排序
     * @param jobj
     * @return
     */
    private static List<String> JsonObjSort(JSONObject jobj) throws JSONException {
		/*Iterator<String> keylist = jobj.sortedKeys();
		List<String> list = new ArrayList<>();
		while (keylist.hasNext()) {
			String key = (String) keylist.next();
			list.add(key);
		}*/
        JSONArray array = jobj.names();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < array.length(); i++) {
            list.add(array.getString(i));
        }
        Collections.sort(list, Collator.getInstance(java.util.Locale.CHINA));
        return list;
    }

    private static String getJobjKeyValue(Object jobj) {
        try
        {
            if (jobj==null)
            {
                return "";
            }
            switch (jobj.getClass().getName()){
                case "java.lang.String":
                    return jobj.toString();
                case "java.lang.Integer":
                    return jobj.toString();
                default:
                    JSONObject vobj=(JSONObject)jobj;
                    List<String> keylist = JsonObjSort(vobj);
                    String valuess = "";
                    for (String key : keylist) {
                        Object obj = vobj.get(key);
                        valuess += (key + "=" + getJobjKeyValue(obj)+"&");
                    }
                    return valuess.substring(0, valuess.length()-1);
            }
        }
        catch (Exception e) {
            return "";
        }
    }

    /*
     * 排序+加密+验证
     */
    public static boolean signature(String s,String signkey){
        JSONObject jsonObj = null;
        try {
            String sign=getDataSign(s, signkey);
            jsonObj = new JSONObject(s);
            if (jsonObj.has("sign"))
            {
                return sign.equals(jsonObj.getString("sign"));
            }
            else
            {
                return false;
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
    }

    /*
     * 排序+key加密
     */
    public static String getDataSign(String s, String signkey) {
        JSONObject jsonObj = null;
        try {
            jsonObj = new JSONObject(s);
            // 获取并剔除sign
            if (jsonObj.has("sign")) {
                jsonObj.remove("sign");
            }
            List<String> keylist = JsonObjSort(jsonObj);
            String valuess = "";
            for (String key : keylist) {
                Object obj = jsonObj.get(key);
                valuess += (key + "=" + getJobjKeyValue(obj) +"&");
            }
            if (!signkey.equals("")){
                valuess+= "key=" + signkey;
            }else{
                valuess=valuess.substring(0,valuess.length()-1);
            }
            // md5加密
            MD5 m = new MD5();
            String md5 = m.GetMD5Code(valuess).toUpperCase();
            return md5;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    // 全局数组
    private final static String[] strDigits = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    public MD5() {
    }

    // 返回形式为数字跟字符串
    private static String byteToArrayString(byte bByte) {
        int iRet = bByte;
        // System.out.println("iRet="+iRet);
        if (iRet < 0) {
            iRet += 256;
        }
        int iD1 = iRet / 16;
        int iD2 = iRet % 16;
        return strDigits[iD1] + strDigits[iD2];
    }

    // 返回形式只为数字
    private static String byteToNum(byte bByte) {
        int iRet = bByte;
        System.out.println("iRet1=" + iRet);
        if (iRet < 0) {
            iRet += 256;
        }
        return String.valueOf(iRet);
    }

    // 转换字节数组为16进制字串
    private static String byteToString(byte[] bByte) {
        StringBuffer sBuffer = new StringBuffer();
        for (int i = 0; i < bByte.length; i++) {
            sBuffer.append(byteToArrayString(bByte[i]));
        }
        return sBuffer.toString();
    }

    public static String GetMD5Code(String strObj) {
        String resultString = null;
        try {
            resultString = new String(strObj);
            MessageDigest md = MessageDigest.getInstance("MD5");
            // md.digest() 该函数返回值为存放哈希值结果的byte数组
            resultString = byteToString(md.digest(strObj.getBytes()));
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        return resultString;
    }

}
